home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Utilities / DocUtils.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  37.4 KB  |  1,293 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DocUtils.cpp
  3.  
  4.     Contains:    code for useful high level Document/Draft utilities
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1995 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>     7/11/96    TJ        Added ODClearIsUnsavedNewDocument
  13.          <5>      6/6/96    EL        1321410: When document is closed, if it is
  14.                                     an UnsavedNewDocument, delete it.
  15.          <4>     5/31/96    jpa        T10012: ODNewDocument sets file creator
  16.                                     (for CyberDog).
  17.          <3>     5/22/96    EL        #1304982: When reverting document, do not
  18.                                     sync file to prop because file name change
  19.                                     is not consider revertable(for now).
  20.          <2>    .04.1996    NP        1330731: Don't use stationery property
  21.                                     anymore.
  22.  
  23.     To Do:
  24.     In Progress:
  25.         
  26. */
  27.  
  28. #ifndef _DOCUTILS_
  29. #include "DocUtils.h"
  30. #endif
  31.  
  32. #ifndef SOM_ODDispatcher_xh
  33. #include "Disptch.xh"
  34. #endif
  35.  
  36. #ifndef _ODUTILS_
  37. #include <ODUtils.h>
  38. #endif
  39.  
  40. #ifndef _EXCEPT_
  41. #include "Except.h"
  42. #endif
  43.  
  44. #ifndef SOM_ODFrame_xh
  45. #include "Frame.xh"
  46. #endif
  47.  
  48. #ifndef _STDTYPIO_
  49. #include "StdTypIO.h"
  50. #endif
  51.  
  52. #ifndef _TEMPOBJ_
  53. #include "TempObj.h"
  54. #endif
  55.  
  56. #ifndef _INFOUTIL_
  57. #include "InfoUtil.h"
  58. #endif
  59.  
  60. #ifndef _BNDNSUTL_
  61. #include "BndNSUtl.h"
  62. #endif
  63.  
  64. #ifndef _STORUTIL_
  65. #include "StorUtil.h"        // for GetFileContainer, code could be inline instead. -TÇ
  66. #endif
  67.  
  68. #ifndef _REFCTCOL_
  69. #include "RefCtCol.h"
  70. #endif
  71.  
  72. #ifndef SOM_ODDispatcher_xh
  73. #include <Disptch.xh>
  74. #endif
  75.  
  76. #ifndef SOM_ODUndo_xh
  77. #include <Undo.xh>
  78. #endif
  79.  
  80. #ifndef SOM_ODInfo_xh
  81. #include <Info.xh>
  82. #endif
  83.  
  84. #ifndef SOM_ODClipboard_xh
  85. #include <Clipbd.xh>
  86. #endif
  87.  
  88. #ifndef SOM_ODLinkManager_xh
  89. #include <LinkMgr.xh>
  90. #endif
  91.  
  92. #ifndef SOM_ODWindowState_xh
  93. #include <WinStat.xh>
  94. #endif
  95.  
  96. #ifndef SOM_ODWindowIterator_xh
  97. #include <WinIter.xh>
  98. #endif
  99.  
  100. #ifndef SOM_ODPart_xh
  101. #include <Part.xh>
  102. #endif
  103.  
  104. #ifndef SOM_ODStorageUnit_xh
  105. #include <StorageU.xh>
  106. #endif
  107.  
  108. #ifndef SOM_ODDraft_xh
  109. #include <Draft.xh>
  110. #endif
  111.  
  112. #ifndef SOM_ODDocument_xh
  113. #include <Document.xh>
  114. #endif
  115.  
  116. #ifndef SOM_ODContainer_xh
  117. #include <ODCtr.xh>
  118. #endif
  119.  
  120. #ifndef _TIME
  121. #include <time.h>
  122. #endif
  123.  
  124. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  125. #include <StdTypes.xh>
  126. #endif
  127.  
  128. #ifndef SOM_Module_OpenDoc_StdProps_defined
  129. #include <StdProps.xh>
  130. #endif
  131.  
  132. #ifndef SOM_ODSession_xh
  133. #include <ODSessn.xh>
  134. #endif
  135.  
  136. #ifndef SOM_ODObjectNameSpace_xh
  137. #include "ObjectNS.xh"
  138. #endif
  139.  
  140. #ifndef SOM_ODNameSpaceManager_xh
  141. #include <NmSpcMg.xh>
  142. #endif
  143.  
  144. #ifndef SOM_ODObjectIterator_xh
  145. #include <ObjctItr.xh>
  146. #endif
  147.  
  148. #ifndef _NMSPCUTL_
  149. #include <NmSpcUtl.h>
  150. #endif
  151.  
  152. #ifndef __TOOLUTILS__
  153. #include <ToolUtils.h>
  154. #endif
  155.  
  156. #ifndef __ICONS__
  157. #include <Icons.h>
  158. #endif
  159.  
  160. #ifndef _ODDEBUG_
  161. #include "ODDebug.h"
  162. #endif
  163.  
  164. #include <stdio.h>
  165.  
  166.  
  167. //==============================================================================
  168. // Constants
  169. //==============================================================================
  170.  
  171. const ODISOStr        kODRefNumDocument            =    "RefNumDocument";
  172. const ODISOStr        kODDocumentTempDraft        =    "DocumentTempDraft";
  173.  
  174. const  ODPropertyName kODPropUnsavedDocument    =    "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:UnsavedDocument";
  175. const  ODPropertyName kODPropTempDocument        =    "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:TempDocument";
  176.  
  177.  
  178. static ODUByte gDUHex[] = "0123456789ABCDEF";
  179.  
  180. /* Constants to specify the file fork GetLocalPaths should match */
  181. enum
  182. {
  183.     kDataFork        = 0,
  184.     kResourceFork    = 1
  185. };
  186.  
  187. //==============================================================================
  188. // Local functions
  189. //==============================================================================
  190.  
  191. static void        ODCreateISOStrKeyFromULong(ODULong    uLongKey, char str[9]);
  192.  
  193. static ODULong    ODGetODULongFromISOStrKey(ODISOStr isoStrKey);
  194.  
  195. static void        SyncFileToProperties(Environment* ev, ODSession* session, ODDocument* document);
  196. static void        SyncPropertiesToFile(Environment* ev, ODSession* session, ODDocument* document);
  197.  
  198. static ODFileRefNum    ODDeduceRefNum(Environment* ev, PlatformFile* file, 
  199.                     ODULong prevRefNumCount, ODSShort* prevRefNums);
  200.                     
  201. //------------------------------------------------------------------------------
  202. // Namespace key utilities
  203. //------------------------------------------------------------------------------
  204.  
  205. void    ODCreateISOStrKeyFromULong(ODULong    uLongKey, char str[9])
  206. {
  207.     sprintf(str,"%.8lX",uLongKey);
  208. /*
  209.     for (ODUByte i = 0; i<sizeof(ODULong); ++i)
  210.     {
  211.         ODUByte b = ((ODUByte*)(&uLongKey))[i];
  212.         ret[i*2] = gDUHex[b / 16];
  213.         ret[i*2 + 1] = gDUHex[b % 16];
  214.     }
  215. */
  216. }
  217.  
  218.  
  219. ODULong        ODGetODULongFromISOStrKey(ODISOStr isoStrKey)
  220. {
  221.     ODULong ret;
  222.     for (ODUByte i = 0; i<sizeof(ODULong); ++i)
  223.     {
  224.         ODUByte n1 = 0, n2 = 0;
  225.         n1 = isoStrKey[i*2];
  226.         n2 = isoStrKey[i*2+1];
  227.         if (n1>'9') 
  228.             n1=n1-'A'+10;
  229.         else 
  230.             n1=n1-'0';
  231.         if (n2>'9') 
  232.             n2=n2-'A'+10;
  233.         else 
  234.             n2=n2-'0';
  235.         
  236.         ((ODUByte*)(&ret))[i] = n1*16 + n2;
  237.     }
  238.     return ret;
  239. }
  240.  
  241.  
  242. //------------------------------------------------------------------------------
  243. // ODDeduceRefNum
  244. //------------------------------------------------------------------------------
  245.  
  246. ODFileRefNum    ODDeduceRefNum(Environment* ev, PlatformFile* file, 
  247.                     ODULong prevRefNumCount, ODSShort* prevRefNums)
  248. {
  249.     ODFileRefNum    retval = 0;
  250.     ODULong         newRefNumCount = 0;
  251.     ODSShort*         newRefNums = kODNULL;
  252.     file->GetLocalPaths(kDataFork, &newRefNumCount, &newRefNums);
  253.  
  254.     WASSERT(newRefNumCount == prevRefNumCount + 1);
  255.  
  256.     ODULong i = 0,j;
  257.     ODBoolean found = kODFalse;
  258.     
  259.     while  (i<newRefNumCount)
  260.     {
  261.         j = 0;
  262.         while (j<prevRefNumCount && (found = (newRefNums[i] == prevRefNums[j]))==kODFalse)
  263.             ++j;
  264.         if (!found)
  265.             break;
  266.         ++i;
  267.     }
  268.     
  269.     WASSERT(i<newRefNumCount);
  270.     
  271.     retval = newRefNums[i];
  272.     
  273.     if (newRefNums) 
  274.         ODDisposePtr((Ptr)newRefNums);
  275.     
  276.     return retval;
  277. }
  278.  
  279.  
  280.  
  281. //==============================================================================
  282. // Opening an file/container/document/draft
  283. //==============================================================================
  284.  
  285.  
  286. void ODAcquireCtrDocTopDraft(Environment* ev, ODSession* session,PlatformFile* file,
  287.         ODContainer** container, ODDocument** document, ODDraft** draft)
  288. {
  289.     *container = GetFileContainer(ev, session, &(file->GetFileSpec()));
  290.     *document = (*container)->AcquireDocument(ev,kODDefaultDocument);
  291.     *draft = (*document)->AcquireDraft(ev,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
  292. }
  293.  
  294. //------------------------------------------------------------------------------
  295. // ODGetFirstOpenDocument
  296. //------------------------------------------------------------------------------
  297.  
  298. ODDocument*    ODGetFirstOpenDocument(Environment* ev, ODSession* session)
  299. {
  300.     return ODGetNthOpenDocument(ev, session, 1);
  301. }
  302.                 
  303. //------------------------------------------------------------------------------
  304. // ODGetNthOpenDocument
  305. //
  306. // n is 1 based & returns kODNULL if there is no nth document
  307. //------------------------------------------------------------------------------
  308.  
  309. ODDocument*    ODGetNthOpenDocument(Environment* ev, ODSession* session, ODULong n)
  310. {
  311.     WASSERT(session != kODNULL);
  312.     
  313.     if (!session)
  314.         THROW(kODErrIllegalNullInput);
  315.         
  316.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  317.     ODObjectNameSpace* refNumDocumentNameSpace = 
  318.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  319.                                                         kODRefNumDocument);
  320.     RETURN_IF_NULL(refNumDocumentNameSpace, kODNULL);
  321.     
  322.     ODObjectIterator* iter = refNumDocumentNameSpace->CreateIterator(ev);
  323.     ODDocument* document = kODNULL;
  324.     ODISOStr unusedKey = kODNULL;
  325.     ODULong unusedObjectLength;
  326.     iter->First(ev, &unusedKey, (ODObject**)&document, &unusedObjectLength);
  327.     while (--n > 0 && document != kODNULL)
  328.     {
  329.         ODDisposePtr(unusedKey);
  330.         unusedKey = kODNULL;
  331.         document = kODNULL;
  332.         iter->Next(ev, &unusedKey, (ODObject**)&document, &unusedObjectLength);
  333.     }
  334.     ODDisposePtr(unusedKey);
  335.     ODDeleteObject(iter);
  336.     return document;
  337. }
  338.                 
  339. //------------------------------------------------------------------------------
  340. // ODGetOpenDocumentFromRefNum
  341. //------------------------------------------------------------------------------
  342.  
  343. ODDocument*    ODGetOpenDocumentFromRefNum(Environment* ev, ODSession* session,
  344.                 ODFileRefNum refnum)
  345. {
  346.     WASSERT(session != kODNULL);
  347.  
  348.     if (!session)
  349.         THROW(kODErrIllegalNullInput);
  350.         
  351.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  352.     ODObjectNameSpace* refNumDocumentNameSpace = 
  353.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  354.                                                         kODRefNumDocument);
  355.     RETURN_IF_NULL(refNumDocumentNameSpace, kODNULL);
  356.     ODDocument* document = kODNULL;
  357.     char key[9];
  358.     ODCreateISOStrKeyFromULong(refnum,key);
  359.     refNumDocumentNameSpace->GetEntry(ev, key, (ODObject**)&document);
  360.     return document;
  361. }
  362.                 
  363. //------------------------------------------------------------------------------
  364. // ODGetTempDraftFromOpenDocument
  365. //------------------------------------------------------------------------------
  366.                 
  367. ODDraft*    ODGetTempDraftFromOpenDocument(Environment* ev, ODSession* session,
  368.                 ODDocument* document)
  369. {
  370.     RETURN_IF_NULL(document, kODNULL);
  371.  
  372.     WASSERT(session != kODNULL);
  373.     if (!session)
  374.         THROW(kODErrIllegalNullInput);
  375.         
  376.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  377.  
  378.     ODObjectNameSpace* documentTempDraftNameSpace = 
  379.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  380.                                                         kODDocumentTempDraft);
  381.     RETURN_IF_NULL(documentTempDraftNameSpace, kODNULL);
  382.     ODDraft* draft = kODNULL;
  383.     char key[9];
  384.     ODCreateISOStrKeyFromULong((ODULong)document,key);
  385.     documentTempDraftNameSpace->GetEntry(ev, key, (ODObject**)&draft);
  386.     return draft;
  387. }
  388.  
  389. //------------------------------------------------------------------------------
  390. // ODTempDraftCreated
  391. //------------------------------------------------------------------------------
  392.                 
  393. void    ODTempDraftCreated(Environment* ev, ODSession* session, 
  394.             ODDocument* document, ODDraft* tempDraft)
  395. {
  396.     WASSERT(session != kODNULL);
  397.     WASSERT(document != kODNULL);
  398.     WASSERT(tempDraft != kODNULL);
  399.  
  400.     if (!session)
  401.         THROW(kODErrIllegalNullInput);
  402.     if (!document)
  403.         THROW(kODErrIllegalNullDocumentInput);
  404.     if (!tempDraft)
  405.         THROW(kODErrIllegalNullDraftInput);
  406.         
  407.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  408.  
  409.     ODObjectNameSpace* nameSpace =    
  410.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  411.                                                         kODDocumentTempDraft);
  412.     if (!nameSpace)
  413.     {
  414.         nameSpace = 
  415.             (ODObjectNameSpace*)theNameSpaceManager->CreateNameSpace(
  416.                 ev, kODDocumentTempDraft, kODNULL, 5, kODNSDataTypeODObject);
  417.     }
  418.     
  419.     {
  420.         char key[9];
  421.         ODCreateISOStrKeyFromULong((ODULong)document,key);
  422.         ODDraft* unusedDraft;
  423.         if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDraft))
  424.             nameSpace->Unregister(ev, key);
  425.         nameSpace->Register(ev, key, tempDraft);
  426.     }
  427. }
  428.  
  429. //------------------------------------------------------------------------------
  430. // ODDocumentOpened
  431. //------------------------------------------------------------------------------
  432.                 
  433. void        ODDocumentOpened(Environment* ev, ODSession* session,
  434.                 ODFileRefNum refnum, ODDocument* document, ODDraft* tempDraft)
  435. {
  436.     WASSERT(session != kODNULL);
  437.     WASSERT(document != kODNULL);
  438.  
  439.     if (!session)
  440.         THROW(kODErrIllegalNullInput);
  441.     if (!document)
  442.         THROW(kODErrIllegalNullDocumentInput);
  443.         
  444.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  445.  
  446.     document->Acquire(ev);    // Balanced by Release in ODDocumentClosed.
  447.     document->GetContainer(ev)->Acquire(ev); // Balanced by Release in ODDocumentClosed.
  448.  
  449.     //• it's not clear whether ODDocumentClosed needs to be called if this fn fails.
  450.     //• Failure halfway through leaves things in an inconsistent state and it doesn't
  451.     //• look like there's any way to clean up fully.
  452.  
  453.     ODObjectNameSpace* nameSpace = 
  454.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  455.                                                         kODRefNumDocument);
  456.     if (!nameSpace)
  457.     {
  458.         nameSpace = 
  459.             (ODObjectNameSpace*)theNameSpaceManager->CreateNameSpace(
  460.                 ev, kODRefNumDocument, kODNULL, 5, kODNSDataTypeODObject);
  461.     }
  462.     
  463.     {
  464.         char key[9];
  465.         ODCreateISOStrKeyFromULong((ODULong)refnum,key);
  466. #if ODDebug
  467.         ODDocument* unusedDocument;
  468.         if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDocument))
  469.             WARN("refnum already in kODRefNumDocument namespace!");
  470. #endif
  471.         nameSpace->Register(ev, key, document);
  472.     }
  473.     
  474.     if (tempDraft)
  475.         ODTempDraftCreated(ev, session, document, tempDraft);
  476. }
  477.                 
  478. //------------------------------------------------------------------------------
  479. // ODDocumentClosed
  480. //------------------------------------------------------------------------------
  481.                 
  482. void    ODDocumentClosed(Environment* ev, ODSession* session,
  483.                 ODDocument* document)
  484. {
  485.     WASSERT(session != kODNULL);
  486.     WASSERT(document != kODNULL);
  487.  
  488.     if (!session)
  489.         THROW(kODErrIllegalNullInput);
  490.     if (!document)
  491.         THROW(kODErrIllegalNullDocumentInput);
  492.         
  493.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  494.     ODObjectNameSpace* nameSpace;
  495.     
  496.     nameSpace = 
  497.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  498.                                                     kODDocumentTempDraft);
  499.     if (nameSpace)
  500.     {
  501.         char key[9];
  502.         ODCreateISOStrKeyFromULong((ODULong)document,key);
  503.         ODDraft* unusedDraft;
  504.         if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDraft))
  505.             nameSpace->Unregister(ev, key);
  506.     }
  507.     
  508.     nameSpace = 
  509.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  510.                                                         kODRefNumDocument);
  511.     if (!nameSpace)
  512.         return;
  513.  
  514.     ODDocument* entryDocument = kODNULL;
  515.     ODISOStr key = kODNULL;
  516.     ODULong unusedObjectLength;
  517.     ODObjectIterator* iter = nameSpace->CreateIterator(ev);
  518.     for (iter->First(ev, &key, (ODObject**)&entryDocument, &unusedObjectLength);
  519.          iter->IsNotComplete(ev);
  520.          iter->Next(ev, &key, (ODObject**)&entryDocument, &unusedObjectLength))
  521.     {
  522.         TempODISOStr tempKey = key; // DMc: ensure it's deleted
  523.         if (ODObjectsAreEqual(ev, document, entryDocument))
  524.         {
  525.             nameSpace->Unregister(ev, key);
  526.             ODContainer* container = document->GetContainer(ev);
  527.             ODFinalReleaseObject(ev, document);
  528.             ODFinalReleaseObject(ev, container);
  529.             break;
  530.         }
  531.     }
  532.     ODDeleteObject(iter);
  533. }
  534.  
  535.  
  536. //==============================================================================
  537. // Root Part/StorageUnit
  538. //==============================================================================
  539.  
  540. //------------------------------------------------------------------------------
  541. // ODAcquireRootPartOfDraft
  542. //------------------------------------------------------------------------------
  543.  
  544. ODPart* ODAcquireRootPartOfDraft(Environment* ev, ODDraft* draft)
  545. {
  546.     if (!draft)
  547.         THROW(kODErrIllegalNullDraftInput);
  548.         
  549.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  550.     return draft->
  551.         AcquirePart(ev,ODGetStrongSURefProp(ev, su, kODPropRootPartSU, kODStrongStorageUnitRef));
  552. }
  553.  
  554. //------------------------------------------------------------------------------
  555. // ODAcquireRootPartSUOfDraft
  556. //------------------------------------------------------------------------------
  557.  
  558. ODStorageUnit* ODAcquireRootPartSUOfDraft(Environment* ev, ODDraft* draft)
  559. {
  560.     if (!draft)
  561.         THROW(kODErrIllegalNullDraftInput);
  562.         
  563.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  564.     if (!su->Exists(ev, kODPropRootPartSU, kODStrongStorageUnitRef, 0))
  565.         return kODNULL;
  566.         
  567.     return draft->
  568.         AcquireStorageUnit(ev,ODGetStrongSURefProp(ev, su, kODPropRootPartSU, kODStrongStorageUnitRef));
  569. }
  570.  
  571. //------------------------------------------------------------------------------
  572. // ODSetRootPartSUOfDraft
  573. //------------------------------------------------------------------------------
  574.  
  575. void ODSetRootPartSUOfDraft(Environment* ev, ODDraft* draft, ODStorageUnit* rootPartSU)
  576. {
  577.     if (!draft)
  578.         THROW(kODErrIllegalNullDraftInput);
  579.     if (!rootPartSU)
  580.         THROW(kODErrIllegalNullStorageUnitInput);
  581.         
  582.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  583.     ODSetStrongSURefProp(ev, su, kODPropRootPartSU, kODStrongStorageUnitRef,
  584.                         rootPartSU->GetID(ev));
  585. }
  586.  
  587. //------------------------------------------------------------------------------
  588. // ODGetDraftOfWindow
  589. //  Given a window object, get the root part's storageUnit's draft
  590. //------------------------------------------------------------------------------
  591.  
  592. ODDraft* ODGetDraftOfWindow(Environment* ev, ODWindow* window)
  593. {
  594.     RETURN_IF_NULL(window, kODNULL);
  595.         
  596.     TempODPart part = window->GetRootFrame(ev)->AcquirePart(ev);
  597.     return part->GetStorageUnit(ev)->GetDraft(ev);
  598. }
  599.  
  600. //------------------------------------------------------------------------------
  601. // ODResetDateModByInfo
  602. //------------------------------------------------------------------------------
  603.  
  604. void ODResetDateModByInfo(Environment* ev, ODStorageUnit* su)
  605. {
  606.     WASSERT(su != kODNULL);
  607.     if (!su)
  608.         THROW(kODErrIllegalNullStorageUnitInput);
  609.  
  610.     WASSERT(HAS_WRITE_ACCESS(su->GetDraft(ev)->GetPermissions(ev)));
  611.             
  612.     ODTime dateTime;
  613.     time((time_t *)(&dateTime));
  614.     ODSetCreationDate(ev, su, dateTime);
  615.     ODSetModificationDate(ev, su, dateTime);
  616.     
  617.     ODIText        modBy;
  618.     su->GetSession(ev)->GetUserName(ev, &modBy);
  619.     TRY
  620.         ODSetModifiedBy(ev, su, &modBy);
  621.     CATCH_ALL
  622.         DisposeITextStruct(modBy);
  623.         RERAISE;
  624.     ENDTRY
  625.     DisposeITextStruct(modBy);
  626.     
  627.     TempODStorageUnit    rootSU = ODAcquireRootPartSUOfDraft(ev, su->GetDraft(ev));
  628.     if (ODObjectsAreEqual(ev, su, rootSU))
  629.     {
  630.         TempPlatformFile    file = GetPlatformFileFromContainer(ev, 
  631.             su->GetDraft(ev)->GetDocument(ev)->GetContainer(ev));
  632.         TempODName             partname = file->GetName();
  633.         //ODSetPOName(ev, rootPart, partname); // don't want to have to have the part so…
  634.         ODSetITextProp(ev, su, kODPropName, kODMacIText, partname);
  635.     }
  636. }
  637.  
  638. //------------------------------------------------------------------------------
  639. // ODGetDocumentFileName
  640. //------------------------------------------------------------------------------
  641.  
  642. void ODGetDocumentFileName(Environment* ev, ODDocument* document, char* fileName)
  643. {
  644.     TempPlatformFile    file = GetPlatformFileFromContainer(ev, document->GetContainer(ev));
  645.     file->GetAsciiName(fileName, 255);
  646. }
  647.  
  648. //==============================================================================
  649. // Cursor Utils
  650. //==============================================================================
  651.  
  652. void WatchCursor()
  653. {
  654.     SetCursor(*GetCursor(watchCursor));
  655. }
  656.  
  657. void ArrowCursor()
  658. {
  659.     SetCursor(&(ODQDGlobals.arrow));
  660. }
  661.  
  662. //==============================================================================
  663. // Active/Changed Utils
  664. //==============================================================================
  665.  
  666. ODWindow*    ODAcquireActiveWindow(Environment* ev, ODSession* session)
  667. {
  668.     WASSERT(session != kODNULL);
  669.     if (!session)
  670.         THROW(kODErrIllegalNullInput);
  671.         
  672.     return session->GetWindowState(ev)->AcquireActiveWindow(ev);
  673. }
  674.  
  675. ODDraft*    ODGetActiveDraft(Environment* ev, ODSession* session)
  676. {
  677.     TempODWindow window = ODAcquireActiveWindow(ev, session);
  678.     return ODGetDraftOfWindow(ev, window);
  679. }
  680.  
  681. ODDocument*    ODGetActiveDocument(Environment* ev, ODSession* session)
  682. {
  683.     ODDraft* draft = ODGetActiveDraft(ev, session);
  684.     RETURN_IF_NULL(draft, kODNULL);    
  685.     
  686.     return draft->GetDocument(ev);
  687. }
  688.  
  689. ODBoolean    ODDocumentHasChanges(Environment* ev, ODSession* session,
  690.                 ODDocument* document)
  691. {
  692.     ODDraft* draft = ODGetTempDraftFromOpenDocument(ev, session, document);
  693.     RETURN_IF_NULL(draft, kODFalse);    
  694.  
  695.     return draft->ChangedFromPrev(ev);
  696. }
  697.  
  698. ODBoolean    ODDocumentHasWriteAccess(Environment* ev, ODSession* session,
  699.                 ODDocument* document)
  700. {
  701.     return ODDraftHasWriteAccess(ev, ODGetTempDraftFromOpenDocument(ev, session, document));
  702. }
  703.  
  704.  
  705. ODBoolean ODDraftHasWriteAccess(Environment* ev, ODDraft* draft)
  706. {
  707.     RETURN_IF_NULL(draft, kODFalse);    
  708.     
  709.     return HAS_WRITE_ACCESS(draft->GetPermissions(ev));
  710. }
  711.  
  712. //==============================================================================
  713. // User level document operations
  714. //==============================================================================
  715.  
  716. //------------------------------------------------------------------------------
  717. // ODNewDocument
  718. //------------------------------------------------------------------------------
  719.  
  720. #define    kODErrEditorLibraryNotFound                -29816
  721. // error code copied from the Shell (RlShlDef.h)
  722.  
  723. void ODNewDocument(Environment* ev, ODContainer* container,
  724.                             ODType        rootPartKind,
  725.                             ODEditor    rootPartEditor)
  726. {
  727.     TempODDocument    document = container->AcquireDocument(ev, kODDefaultDocument);
  728.     TempODDraft        draft = document->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  729.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  730.  
  731.     ODResetDateModByInfo(ev, su);    
  732.     
  733.   // create new root part
  734.       TempODPart rootPart = kODNULL;
  735.       
  736.       TRY
  737.         rootPart = draft->CreatePart(ev, rootPartKind, rootPartEditor);
  738.     CATCH_ALL
  739.         if (ErrorCode()==fragLibNotFound)
  740.             THROW(kODErrEditorLibraryNotFound);
  741.         else
  742.             RERAISE;
  743.     ENDTRY
  744.     ODStorageUnit* partSU = rootPart->GetStorageUnit(ev);
  745.     if (partSU == kODNULL)
  746.         THROW(kODErrEditorLibraryNotFound);
  747.     ODSetRootPartSUOfDraft(ev, draft, partSU);
  748.  
  749.     ODSetBooleanProp(ev, su, kODPropUnsavedDocument, kODBoolean, kODTrue);
  750.  
  751.     draft->Externalize(ev);
  752.  
  753.     ODPlatformType    rootPartOSType = ODGetIconFilePlatformTypeFromPartSU(ev, partSU);
  754.     ODPlatformType    rootPartCreator= ODGetIconFilePlatformCreator(ev,rootPart);
  755.  
  756.     TempPlatformFile file = GetPlatformFileFromContainer(ev, container);
  757.     file->SetPlatformType(rootPartOSType);
  758.     file->SetPlatformCreator(rootPartCreator);
  759. }
  760.  
  761. //------------------------------------------------------------------------------
  762. // ODIsUnsavedNewDocument
  763. //------------------------------------------------------------------------------
  764.  
  765. ODBoolean ODIsUnsavedNewDocument(Environment* ev, ODSession* session, ODDocument* document)
  766. {
  767.     ODDraft* draft = ODGetTempDraftFromOpenDocument(ev, session, document);
  768.     RETURN_IF_NULL(draft, kODFalse);
  769.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  770.     if (!su->Exists(ev, kODPropUnsavedDocument, kODBoolean, 0))
  771.         return kODFalse;
  772.     return ODGetBooleanProp(ev, su, kODPropUnsavedDocument, kODBoolean);
  773. }
  774.  
  775. //------------------------------------------------------------------------------
  776. // ODSetIsUnsavedNewDocument
  777. //------------------------------------------------------------------------------
  778.  
  779. void ODSetIsUnsavedNewDocument(Environment* ev, ODDraft* draft)
  780. {
  781.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  782.     ODSetBooleanProp(ev, su, kODPropUnsavedDocument, kODBoolean, kODTrue);
  783. }
  784.  
  785. //------------------------------------------------------------------------------
  786. // ODClearIsUnsavedNewDocument
  787. //------------------------------------------------------------------------------
  788.  
  789. void ODClearIsUnsavedNewDocument(Environment* ev, ODDraft* draft)
  790. {
  791.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  792.     if (su->Exists(ev, kODPropUnsavedDocument, kODBoolean, 0))
  793.         ODSURemoveProperty(ev, su, kODPropUnsavedDocument);
  794. }
  795. //------------------------------------------------------------------------------
  796. // ODOpenFileDocument
  797. //------------------------------------------------------------------------------
  798.  
  799. ODDraft* ODOpenFileDocument(Environment* ev, ODSession* session, PlatformFile* file,
  800.     ODDraftPermissions permissions)
  801. {
  802.     WASSERT(session != kODNULL);
  803.     WASSERT(file != kODNULL);
  804.  
  805.     if (!session)
  806.         THROW(kODErrIllegalNullInput);
  807.     if (!file)
  808.         THROW(kODErrIllegalNullInput);
  809.  
  810.     ODContainer*    container    = kODNULL;
  811.     ODDocument*        document    = kODNULL;
  812.     ODDraft*        currentdraft    = kODNULL;
  813.     ODDraft*        tempdraft    = kODNULL;
  814.     
  815.     ODULong refNumCount, i;
  816.     ODSShort* refNums = kODNULL;
  817.     file->GetLocalPaths(kDataFork, &refNumCount, &refNums);
  818.     
  819.     for ( i=0; i<refNumCount; ++i)
  820.         if ((document = ODGetOpenDocumentFromRefNum(ev, session, refNums[i])) != kODNULL)
  821.         {
  822.             currentdraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  823.             if (currentdraft)
  824.                 currentdraft->Acquire(ev);
  825.             else
  826.                 currentdraft = document->AcquireDraft(ev,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
  827.             if (refNums)
  828.                 ODDisposePtr(refNums);
  829.             return currentdraft;
  830.         }
  831.  
  832.     // ODAcquireCtrDocTopDraft opens the file and adds a new refnum.
  833.  
  834.     ODAcquireCtrDocTopDraft(ev, session, file, &container, &document, ¤tdraft);
  835.     TempODContainer tempCont = container;        // Ensures they're released
  836.     TempODDocument  tempDoc  = document;
  837.     ODFileRefNum    refnum = ODDeduceRefNum(ev, file, refNumCount, refNums);
  838.     if (refNums)
  839.         ODDisposePtr(refNums);
  840.     
  841.     if (HAS_WRITE_ACCESS(permissions) && !file->IsLocked())
  842.     {
  843.         currentdraft = 
  844.             document->AcquireDraft(ev, permissions,0, currentdraft, kODPosSame, kODTrue);
  845.         currentdraft = document->CreateDraft(ev, currentdraft, kODTrue);
  846.         tempdraft = currentdraft;
  847.         tempdraft->Acquire(ev); 
  848.             // Because "The caller is responsible for properly refcounting the tempdraft."
  849.             // From DocUtils.h documentation of ODDocumentOpened.
  850.     }
  851.             
  852.     ODDocumentOpened(ev, session, refnum, document, tempdraft);
  853.     
  854.     return currentdraft;
  855. }
  856.  
  857. //------------------------------------------------------------------------------
  858. // ODOpenDraft
  859. //------------------------------------------------------------------------------
  860.  
  861. void ODOpenDraft(Environment* ev, ODSession* session, ODDraft* draft)
  862. {
  863.     WASSERT(session != kODNULL);
  864.     WASSERT(draft != kODNULL);
  865.  
  866.     if (!session)
  867.         THROW(kODErrIllegalNullInput);
  868.     if (!draft)
  869.         THROW(kODErrIllegalNullDraftInput);
  870.  
  871.     ODBoolean    windowsOpen = kODFalse;
  872.     ODWindowState* windowState = session->GetWindowState(ev);
  873.  
  874.     windowState->Internalize(ev,draft);
  875.     windowState->OpenWindows(ev, draft);
  876.     windowsOpen = (windowState->GetRootWindowCount(ev, draft)>0);
  877.  
  878.     //need this for NoPart alert 
  879.     if (session->GetDispatcher(ev)->ShouldExit(ev))
  880.         return;
  881.         
  882.     if (!windowsOpen)
  883.     {
  884.         TempODPart    rootPart = ODAcquireRootPartOfDraft(ev, draft);
  885.         rootPart->Open(ev, kODNULL);
  886.         windowState->SetDefaultWindowTitles(ev, draft);
  887.     }
  888.     session->GetLinkManager(ev)->DraftOpened(ev,draft);
  889. }
  890.  
  891. //------------------------------------------------------------------------------
  892. // ODCloseDraft
  893. //------------------------------------------------------------------------------
  894.  
  895. void ODCloseDraft(Environment* ev, ODSession* session, ODDraft* draft)
  896. {
  897.     WASSERT(session != kODNULL);
  898.     WASSERT(draft != kODNULL);
  899.  
  900.     if (!session)
  901.         THROW(kODErrIllegalNullInput);
  902.     if (!draft)
  903.         THROW(kODErrIllegalNullDraftInput);
  904.         
  905.     session->GetLinkManager(ev)->DraftClosing(ev, draft);
  906.     session->GetUndo(ev)->ClearActionHistory(ev, kODDontRespectMarks);
  907.     session->GetClipboard(ev)->DraftClosing(ev, draft);
  908.     session->GetWindowState(ev)->CloseWindows(ev, draft);
  909. }
  910.  
  911. //------------------------------------------------------------------------------
  912. // ODCloseDocument
  913. //------------------------------------------------------------------------------
  914.  
  915. ODBoolean ODCloseDocument(Environment* ev, ODSession* session, ODDocument* document)
  916. {
  917.     RETURN_IF_NULL(document, kODFalse);    // For the caller's convenience.
  918.  
  919.     ODDraft* tempDraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  920.  
  921.     ODRefCntCollection*    draftsWithOpenWindows = new ODRefCntCollection(ev);
  922.  
  923.     TempPlatformFile file = kODNULL; 
  924.  
  925.     ODBoolean isUnsavedNewDocument = ODIsUnsavedNewDocument(ev, session, document);
  926.  
  927.     if (isUnsavedNewDocument)
  928.         file = GetPlatformFileFromContainer(ev, document->GetContainer(ev));
  929.  
  930.     ODWindowIterator* iter = session->GetWindowState(ev)->CreateWindowIterator(ev);
  931.     ODWindow* window = kODNULL;
  932.     while ((window = iter->Next(ev)) != kODNULL)
  933.     {
  934.         // close all windows whose draft's document = document
  935.         ODDraft* draft = ODGetDraftOfWindow(ev, window);
  936.         WASSERT(draft != kODNULL);
  937.         if (ODObjectsAreEqual(ev, document, draft->GetDocument(ev))
  938.             && !draftsWithOpenWindows->Contains(draft))
  939.             draftsWithOpenWindows->AddFirstAndAcquire(draft);
  940.     }
  941.     ODDeleteObject(iter);
  942.  
  943.     ODDraft* draft = kODNULL;
  944.     while ((draft = (ODDraft*)draftsWithOpenWindows->RemoveFirst()) != kODNULL)
  945.     {
  946.         ODCloseDraft(ev, session, draft);
  947.         draft->Release(ev); // to balance AddFirstAndAcquire above.
  948.     }
  949.  
  950.     ODDeleteObject(draftsWithOpenWindows);
  951.     if (tempDraft)
  952.     {
  953.         tempDraft->RemoveChanges(ev);
  954.         WASSERT(tempDraft->GetRefCount(ev) == 1);
  955.         tempDraft->RemoveFromDocument(ev);
  956.     }
  957.     ODDocumentClosed(ev, session, document);
  958.     if (isUnsavedNewDocument)
  959.         file->Delete();
  960.     
  961.     TempODWindow activeWindow = ODAcquireActiveWindow(ev, session);
  962.     return (activeWindow == kODNULL);
  963. }
  964.  
  965. //------------------------------------------------------------------------------
  966. // ODReleaseCloseWindow
  967. //------------------------------------------------------------------------------
  968.  
  969. ODBoolean ODReleaseCloseWindow(Environment* ev, ODSession* session, ODWindow* window)
  970. {
  971.     WASSERT(session != kODNULL);
  972.     WASSERT(window != kODNULL);
  973.  
  974.     if (!session)
  975.         THROW(kODErrIllegalNullInput);
  976.     if (!window)
  977.         THROW(kODErrIllegalNullInput);
  978.  
  979.     WASSERT(window->GetRefCount(ev) > 1);
  980. #if ODDebug
  981.     ODULong windowRefCount = window->GetRefCount(ev);
  982.     if (windowRefCount != 3)
  983.     {
  984.         WARN("Trying to close a window with RefCount of (%d) != 3.", windowRefCount);
  985.         WARN("…expect problems later closing the draft, document and container.-TÇ");
  986.         WARN("Solution? Make sure window is properly refcounted.");
  987.         WARN("Possible Culprit: Part::Open forgetting to release a registered window.");
  988.     }
  989. #endif
  990.     
  991.     ODBoolean wasLastRootWindow = kODFalse;
  992.     ODDraft* draft = ODGetDraftOfWindow(ev, window);
  993.     draft->Acquire(ev);    // necessary just in case closing all windows fully releases the draft
  994.     ODBoolean isOnlyDraftWindow 
  995.         = window->IsRootWindow(ev) && 
  996.         (session->GetWindowState(ev)->GetRootWindowCount(ev, draft) == 1);
  997.     if (isOnlyDraftWindow)
  998.     {
  999.         window->Release(ev);
  1000.         ODCloseDraft(ev, session, draft);
  1001.  
  1002.         ODDocument* document = draft->GetDocument(ev);
  1003.         if (!document->Exists(ev, kODNULLID, draft, kODPosFirstAbove))
  1004.         {
  1005.             ODReleaseObject(ev, draft); // to balance the above Acquire before calling ODCloseDocument.
  1006.             wasLastRootWindow = ODCloseDocument(ev, session, document);
  1007.         }
  1008.     }
  1009.     else
  1010.     {
  1011.         window->CloseAndRemove(ev);
  1012.     }
  1013.     ODReleaseObject(ev, draft);
  1014.     return wasLastRootWindow;
  1015. }
  1016.  
  1017. //------------------------------------------------------------------------------
  1018. // ODDeleteDocument
  1019. //------------------------------------------------------------------------------
  1020.  
  1021. ODBoolean ODDeleteDocument(Environment* ev, ODSession* session, ODDocument* document)
  1022. {
  1023.     WASSERT(session != kODNULL);
  1024.     WASSERT(document != kODNULL);
  1025.  
  1026.     if (!session)
  1027.         THROW(kODErrIllegalNullInput);
  1028.     if (!document)
  1029.         THROW(kODErrIllegalNullDocumentInput);
  1030.         
  1031.     TempPlatformFile    currentFile = 
  1032.         GetPlatformFileFromContainer(ev, document->GetContainer(ev));                            
  1033.     ODBoolean retval = ODCloseDocument(ev, session, document);
  1034.     currentFile->MoveToTrash();
  1035.     return retval;
  1036. }
  1037.  
  1038. //------------------------------------------------------------------------------
  1039. // ODSaveDocument
  1040. //------------------------------------------------------------------------------
  1041.  
  1042. void ODSaveDocument(Environment* ev, ODSession* session, ODDocument* document)
  1043. {
  1044.     WASSERT(session != kODNULL);
  1045.     WASSERT(document != kODNULL);
  1046.  
  1047.     if (!session)
  1048.         THROW(kODErrIllegalNullInput);
  1049.     if (!document)
  1050.         THROW(kODErrIllegalNullDocumentInput);
  1051.  
  1052.     ODDraft* tempDraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  1053.     if (tempDraft)
  1054.     {
  1055.         WatchCursor();
  1056.         session->GetUndo(ev)->ClearActionHistory(ev, kODDontRespectMarks);
  1057.     
  1058.         // Fix desktop information which parallels the rootpart such as:
  1059.         // filename, comments, stationery bit, etc.
  1060.         SyncPropertiesToFile(ev, session, document);
  1061.     
  1062.         TempODStorageUnit su = tempDraft->AcquireDraftProperties(ev);
  1063.         ODSURemoveProperty(ev, su, kODPropUnsavedDocument);
  1064.         
  1065.         session->GetWindowState(ev)->Externalize(ev, tempDraft);
  1066.         tempDraft->Externalize(ev);
  1067.         session->GetLinkManager(ev)->DraftSaved(ev, tempDraft);
  1068.         session->GetClipboard(ev)->DraftSaved(ev, tempDraft);
  1069.     
  1070.         tempDraft->SaveToAPrevious(ev, kODNULL);
  1071.  
  1072.         ArrowCursor();
  1073.         session->GetDispatcher(ev)->InvalidateFacetUnderMouse(ev);
  1074.     }
  1075. }
  1076.  
  1077. //------------------------------------------------------------------------------
  1078. // ODSaveACopyOfDraft
  1079. //    Saves a copy of the draft.
  1080. //------------------------------------------------------------------------------
  1081.  
  1082. void ODSaveACopyOfDraft(Environment* ev, ODSession* session, ODDraft* fromDraft, 
  1083.                         PlatformFile* destinationFile)
  1084. {
  1085.     WASSERT(session != kODNULL);
  1086.     WASSERT(fromDraft != kODNULL);
  1087.     WASSERT(destinationFile != kODNULL);
  1088.  
  1089.     if (!session)
  1090.         THROW(kODErrIllegalNullInput);
  1091.  
  1092.     if (!fromDraft)
  1093.         THROW(kODErrIllegalNullDraftInput);
  1094.  
  1095.     if (!destinationFile)
  1096.         THROW(kODErrIllegalNullInput);
  1097.         
  1098.     WatchCursor();
  1099.     if (ODDraftHasWriteAccess(ev, fromDraft) && fromDraft->ChangedFromPrev(ev))
  1100.     {
  1101.         session->GetWindowState(ev)->Externalize(ev, fromDraft);
  1102.         fromDraft->Externalize(ev);
  1103.     }
  1104.     
  1105.     TempPlatformFile currentFile = 
  1106.         GetPlatformFileFromContainer(ev, fromDraft->GetDocument(ev)->GetContainer(ev));
  1107.     TempODStorageUnit partSU = ODAcquireRootPartSUOfDraft(ev, fromDraft);
  1108.     ODPlatformType fileType = ODGetIconFilePlatformTypeFromPartSU(ev, partSU);
  1109.     destinationFile->Create(currentFile->GetPlatformCreator(),fileType,0);
  1110.     
  1111.     TempODContainer    newContainer = 
  1112.         CreateFileContainer(ev, session, &(destinationFile->GetFileSpec()));    
  1113.     TempODDocument    newDocument = newContainer->AcquireDocument(ev, kODDefaultDocument);
  1114.     newDocument->SetBaseDraftFromForeignDraft(ev, fromDraft);
  1115.     TempODDraft    newDraft = newDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  1116.     TempODStorageUnit su = newDraft->AcquireDraftProperties(ev);
  1117.     ODSURemoveProperty(ev, su, kODPropUnsavedDocument);
  1118.     newDraft->Externalize(ev);
  1119.  
  1120.     ArrowCursor();
  1121. }
  1122.  
  1123.  
  1124. //------------------------------------------------------------------------------
  1125. // ODRevertDocument
  1126. //------------------------------------------------------------------------------
  1127.  
  1128. void ODRevertDocument(Environment* ev, ODSession* session, ODDocument* document)
  1129. {
  1130.     WASSERT(session != kODNULL);
  1131.     WASSERT(document != kODNULL);
  1132.     if (!session)
  1133.         THROW(kODErrIllegalNullInput);
  1134.     if (!document)
  1135.         THROW(kODErrIllegalNullDocumentInput);
  1136.  
  1137.     ODDraft* tempDraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  1138.     if (tempDraft)
  1139.     {
  1140.         WatchCursor();
  1141.         ODCloseDraft(ev, session, tempDraft);    
  1142.         tempDraft->RemoveChanges(ev);
  1143.         ODOpenDraft(ev, session, tempDraft);
  1144. //        SyncFileToProperties(ev, session, document);
  1145.         ArrowCursor();
  1146.         session->GetDispatcher(ev)->InvalidateFacetUnderMouse(ev);
  1147.     }
  1148. }
  1149.  
  1150. //------------------------------------------------------------------------------
  1151. // ODDocumentInfo
  1152. //------------------------------------------------------------------------------
  1153.  
  1154. void ODDocumentInfo(Environment* ev, ODSession* session)
  1155. {
  1156.     WASSERT(session != kODNULL);
  1157.     if (!session)
  1158.         THROW(kODErrIllegalNullInput);
  1159.  
  1160.     ArrowCursor();
  1161.  
  1162.     ODFacet* infoFacet = kODNULL;
  1163.     ODBoolean hasWriteAccess = kODFalse;
  1164.     {
  1165.     TempODWindow window = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
  1166.     infoFacet = window->GetRootFacet(ev);
  1167.     hasWriteAccess = ODDraftHasWriteAccess(ev, ODGetDraftOfWindow(ev, window));
  1168.     }
  1169.     session->GetInfo(ev)->ShowPartFrameInfo(ev, infoFacet, hasWriteAccess);
  1170. }
  1171.  
  1172.  
  1173. //------------------------------------------------------------------------------
  1174. // ODIsTempDocument
  1175. //------------------------------------------------------------------------------
  1176.  
  1177. ODBoolean ODIsTempDocument(Environment* ev, ODSession* session, ODDocument* document)
  1178. {
  1179.     ODDraft* draft = ODGetTempDraftFromOpenDocument(ev, session, document);
  1180.     RETURN_IF_NULL(draft, kODFalse);
  1181.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  1182.     if (!su->Exists(ev, kODPropTempDocument, kODBoolean, 0))
  1183.         return kODFalse;
  1184.     return ODGetBooleanProp(ev, su, kODPropTempDocument, kODBoolean);
  1185. }
  1186.  
  1187. //------------------------------------------------------------------------------
  1188. // ODSetIsTempDocument
  1189. //------------------------------------------------------------------------------
  1190.  
  1191. void ODSetIsTempDocument(Environment* ev, ODDraft* draft, ODBoolean isTemp)
  1192. {
  1193.     if (!draft)
  1194.         return;
  1195.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  1196.     if (isTemp)
  1197.         ODSetBooleanProp(ev, su, kODPropTempDocument, kODBoolean, isTemp);
  1198.     else
  1199.         ODSURemoveProperty(ev, su, kODPropTempDocument);
  1200. }
  1201.  
  1202. //------------------------------------------------------------------------------
  1203. // SyncFileToProperties
  1204. //------------------------------------------------------------------------------
  1205.  
  1206. void SyncFileToProperties(Environment* ev, ODSession* session, ODDocument* document)
  1207. {
  1208.     ODDraft*            tempDraft    = ODGetTempDraftFromOpenDocument(ev, session, document);
  1209.     TempODPart            rootPart    = ODAcquireRootPartOfDraft(ev, tempDraft);
  1210.     ODIText*            foo            = kODNULL;
  1211.     ODIconFamily        icons        = kODNULL;
  1212.     TempPlatformFile    file        = GetPlatformFileFromContainer(ev, document->GetContainer(ev));
  1213.     
  1214.     // filename
  1215.     foo = ODGetPOName(ev, rootPart, kODNULL);
  1216.     if (foo)
  1217.     {
  1218.         Str255    pName;
  1219.         GetITextPString(foo, pName);
  1220.         TRY
  1221.             file->Rename(pName);
  1222.         CATCH_ALL
  1223.         ENDTRY
  1224.         DisposeIText(foo);
  1225.         ODWindowState* windowState = session->GetWindowState(ev);
  1226.         windowState->SetDefaultWindowTitles(ev, tempDraft);
  1227.     }
  1228.     
  1229.     // stationery
  1230. //    file->SetStationery(ODGetSUIsStationery(ev, rootPart->GetStorageUnit(ev)));
  1231.     
  1232.     // comments
  1233.     foo = ODGetPOComments(ev, rootPart, kODNULL);
  1234.     if (foo != kODNULL)
  1235.     {
  1236.         file->SetComments(foo);
  1237.         DisposeIText(foo);
  1238.     }
  1239.  
  1240.     // custom icon
  1241.     icons = ODGetPOIconFamily(ev, rootPart);
  1242.     file->SetCustomIconFamily(icons);
  1243.     if (icons)
  1244.         THROW_IF_ERROR( DisposeIconSuite(icons, kODTrue) );
  1245. }
  1246.  
  1247.  
  1248. //------------------------------------------------------------------------------
  1249. // SyncPropertiesToFile
  1250. //------------------------------------------------------------------------------
  1251.  
  1252. void SyncPropertiesToFile(Environment* ev, ODSession* session, ODDocument* document)
  1253. {
  1254.     TempODWindow        odWindow    = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
  1255.     ODFrame*            frame        = odWindow->GetRootFrame(ev);
  1256.     ODDraft*            tempDraft    = ODGetTempDraftFromOpenDocument(ev, session, document);
  1257.     TempODPart            rootPart    = ODAcquireRootPartOfDraft(ev, tempDraft);
  1258.     ODStorageUnit*        su            = ODGetSUFromPstObj(ev, (ODPart*)rootPart);
  1259.     ODIText*            foo            = kODNULL;
  1260.     ODIconFamily        icons        = kODNULL;
  1261.     TempPlatformFile    file        = GetPlatformFileFromContainer(ev, document->GetContainer(ev));
  1262.     
  1263.     // filename
  1264.     foo = file->GetName();
  1265.     if (foo)
  1266.     {
  1267.         ODSetPOName(ev, rootPart, foo);
  1268.         DisposeIText(foo);
  1269.     }
  1270.     
  1271.     // stationery
  1272. //    ODSetSUIsStationery(ev, su, file->IsStationery());
  1273.  
  1274.     // comments
  1275.     //
  1276.     // this gets comments and makes sure that the file matches the property
  1277.     // we just need to make sure that the property matches the file
  1278.     foo = ODGetComments(ev, frame, kODNULL);
  1279.     if (foo != kODNULL)
  1280.     {
  1281.         ODSetPOComments(ev, rootPart, foo);
  1282.         DisposeIText(foo);
  1283.     }
  1284.  
  1285.     // custom icon
  1286.     icons = file->GetCustomIconFamily();
  1287.     ODSetPOIconFamily(ev, rootPart, icons, kODFalse);
  1288.     if (icons)
  1289.         THROW_IF_ERROR( DisposeIconSuite(icons, kODTrue) );
  1290. }
  1291.  
  1292.  
  1293.